As a reminder, the figure below displays a mile-high view of migration timing across different striped bass spawning groups: Hudson River (HR), Delaware River (DE), and Potomac River (PR). The length of the line displays the range of residence of each group in either the natal estuary (colors) or coastal Massachusetts (yellow). The circle shows the median day of arrival in the given array, and the triangle shows the median date of departure. Only fish that were larger than 800 mm at the time of tagging are shown.

Warning: Invalid .internal.selfref detected and fixed by taking a (shallow)
copy of the data.table so that := can add this new column by reference. At an
earlier point, this data.table has been copied by R (or was created manually
using structure() or similar). Avoid names<- and attr<- which in R currently
(and oddly) may copy the whole data.table. Use set* syntax instead to avoid
copying: ?set, ?setnames and ?setattr. If this message doesn't help, please
report your use case to the data.table issue tracker so the root cause can be
fixed or this message improved.

I’m going to make a quick-and-dirty model to compare the timing of entry into coastal Massachusetts by spawning group. The full model includes day of year (“yday”, numeric), spawning group (“group”, factor), the year (“year”, ordered factor), and all interactions.

The response was modeled as binomial, with the cumulative number of fish that have entered Massachusetts waters per group-year combination considered “successes” and the total number of fish that arrived in coastal MA per group-year combination as the number of trials.

Using step-wise variable selection…

Start:  AIC=876.21
cbind(success, trials - success) ~ 0 + group + yday + year + 
    group:yday + group:year + year:yday + group:year:yday

                  Df Deviance    AIC
<none>                 204.73 876.21
- group:yday:year  6   220.74 880.23

…the variables selected are: group, yday, year, group:yday, group:year, yday:year, group:yday:year.


Call:
glm(formula = cbind(success, trials - success) ~ 0 + group + 
    yday + year + group:yday + group:year + year:yday + group:year:yday, 
    family = "binomial", data = binom_data[array == "MA Coast"])

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.9854  -0.6261   0.0378   0.4881   2.1411  

Coefficients:
                      Estimate Std. Error z value Pr(>|z|)    
groupDE             -15.875824   1.328794 -11.948  < 2e-16 ***
groupHR             -11.264119   1.173194  -9.601  < 2e-16 ***
groupPR             -18.541642   2.964276  -6.255 3.97e-10 ***
yday                  0.097072   0.008390  11.570  < 2e-16 ***
year.L               -8.841642   2.298368  -3.847  0.00012 ***
year.Q               -4.173475   2.657588  -1.570  0.11632    
year.C                4.614116   2.973727   1.552  0.12075    
groupHR:yday         -0.033435   0.010911  -3.064  0.00218 ** 
groupPR:yday          0.014470   0.019871   0.728  0.46650    
groupHR:year.L        8.480084   3.853682   2.201  0.02777 *  
groupPR:year.L        9.320778   7.243423   1.287  0.19817    
groupHR:year.Q       -2.710364   3.545181  -0.765  0.44456    
groupPR:year.Q        0.729079   6.496961   0.112  0.91065    
groupHR:year.C       -4.344584   3.207141  -1.355  0.17553    
groupPR:year.C        4.656374   5.652772   0.824  0.41009    
yday:year.L           0.061693   0.014208   4.342 1.41e-05 ***
yday:year.Q           0.023110   0.016779   1.377  0.16842    
yday:year.C          -0.033881   0.019006  -1.783  0.07464 .  
groupHR:yday:year.L  -0.055324   0.023270  -2.377  0.01743 *  
groupPR:yday:year.L  -0.072239   0.044520  -1.623  0.10467    
groupHR:yday:year.Q   0.018236   0.021822   0.836  0.40333    
groupPR:yday:year.Q   0.002267   0.039743   0.057  0.95451    
groupHR:yday:year.C   0.033170   0.020270   1.636  0.10177    
groupPR:yday:year.C  -0.013135   0.034307  -0.383  0.70181    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 2656.34  on 202  degrees of freedom
Residual deviance:  204.73  on 178  degrees of freedom
AIC: 876.21

Number of Fisher Scoring iterations: 5

When looking at pairwise contrasts by year, the only significant differences occur in 2018, where arrival in MA was more rapid in DE and PR fish when compared to HR fish (greater yday slope).

year = 2016:
 contrast estimate      SE  df z.ratio p.value
 DE - HR  -0.00538 0.00971 Inf  -0.554  0.8443
 DE - PR  -0.06700 0.05253 Inf  -1.275  0.4091
 HR - PR  -0.06162 0.05187 Inf  -1.188  0.4604

year = 2017:
 contrast estimate      SE  df z.ratio p.value
 DE - HR   0.00793 0.00513 Inf   1.547  0.2691
 DE - PR  -0.02068 0.02399 Inf  -0.862  0.6644
 HR - PR  -0.02861 0.02372 Inf  -1.206  0.4494

year = 2018:
 contrast estimate      SE  df z.ratio p.value
 DE - HR   0.07717 0.02762 Inf   2.794  0.0144
 DE - PR  -0.00599 0.03971 Inf  -0.151  0.9875
 HR - PR  -0.08317 0.02924 Inf  -2.845  0.0124

year = 2019:
 contrast estimate      SE  df z.ratio p.value
 DE - HR   0.05401 0.03196 Inf   1.690  0.2090
 DE - PR   0.03579 0.03750 Inf   0.955  0.6056
 HR - PR  -0.01822 0.04316 Inf  -0.422  0.9064

P value adjustment: tukey method for comparing a family of 3 estimates 
NOTE: Results may be misleading due to involvement in interactions
$emmeans
year = 2016:
 group emmean     SE  df asymp.LCL asymp.UCL
 DE     1.376 0.2072 Inf     0.970     1.782
 HR     0.953 0.0709 Inf     0.814     1.092
 PR     4.711 1.7653 Inf     1.251     8.171

year = 2017:
 group emmean     SE  df asymp.LCL asymp.UCL
 DE     0.738 0.1255 Inf     0.492     0.984
 HR     0.364 0.0666 Inf     0.233     0.495
 PR     2.738 1.0116 Inf     0.755     4.721

year = 2018:
 group emmean     SE  df asymp.LCL asymp.UCL
 DE     4.691 1.0661 Inf     2.602     6.780
 HR     0.575 0.1176 Inf     0.344     0.805
 PR     1.778 0.4627 Inf     0.871     2.685

year = 2019:
 group emmean     SE  df asymp.LCL asymp.UCL
 DE     4.627 0.5827 Inf     3.485     5.769
 HR     2.177 0.7645 Inf     0.678     3.675
 PR     2.711 0.9279 Inf     0.893     4.530

Results are averaged over the levels of: yday 
Results are given on the logit (not the response) scale. 
Confidence level used: 0.95 

$contrasts
year = 2016:
 contrast estimate    SE  df z.ratio p.value
 DE - HR     0.423 0.219 Inf   1.929  0.1304
 DE - PR    -3.335 1.777 Inf  -1.876  0.1455
 HR - PR    -3.758 1.767 Inf  -2.127  0.0844

year = 2017:
 contrast estimate    SE  df z.ratio p.value
 DE - HR     0.374 0.142 Inf   2.635  0.0229
 DE - PR    -2.000 1.019 Inf  -1.962  0.1218
 HR - PR    -2.374 1.014 Inf  -2.342  0.0502

year = 2018:
 contrast estimate    SE  df z.ratio p.value
 DE - HR     4.116 1.073 Inf   3.838  0.0004
 DE - PR     2.913 1.162 Inf   2.506  0.0327
 HR - PR    -1.203 0.477 Inf  -2.521  0.0314

year = 2019:
 contrast estimate    SE  df z.ratio p.value
 DE - HR     2.450 0.961 Inf   2.549  0.0291
 DE - PR     1.915 1.096 Inf   1.748  0.1875
 HR - PR    -0.535 1.202 Inf  -0.445  0.8967

Results are averaged over the levels of: yday 
Results are given on the log odds ratio (not the response) scale. 
P value adjustment: tukey method for comparing a family of 3 estimates 

Entry into MA waters significantly different between DE and HR fish, but not between PR and HR or PR and DE fish.

Start:  AIC=991.5
cbind(success, trials - success) ~ 0 + group + yday + group:yday + 
    year

             Df Deviance     AIC
<none>            382.39  991.50
- group:yday  2   394.16  999.26
- year        3   528.96 1132.06

Call:
glm(formula = cbind(success, trials - success) ~ 0 + group + 
    yday + group:yday + year, family = "binomial", data = binom_data[array == 
    "MA Coast"])

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.0910  -0.9008   0.0119   0.9630   5.2940  

Coefficients:
               Estimate Std. Error z value Pr(>|z|)    
groupDE       -8.542018   0.499708 -17.094  < 2e-16 ***
groupHR      -11.015699   0.352014 -31.293  < 2e-16 ***
groupPR      -10.413725   1.745313  -5.967 2.42e-09 ***
yday           0.033748   0.001915  17.623  < 2e-16 ***
year2017      -0.374309   0.070063  -5.342 9.17e-08 ***
year2018       0.906559   0.108262   8.374  < 2e-16 ***
year2019       0.300201   0.130164   2.306 0.021092 *  
groupHR:yday   0.008022   0.002301   3.486 0.000491 ***
groupPR:yday   0.007858   0.007130   1.102 0.270393    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 2536.41  on 192  degrees of freedom
Residual deviance:  382.39  on 183  degrees of freedom
AIC: 991.5

Number of Fisher Scoring iterations: 5
$emtrends
 group yday.trend      SE  df asymp.LCL asymp.UCL
 DE        0.0337 0.00191 Inf    0.0300    0.0375
 HR        0.0418 0.00133 Inf    0.0392    0.0444
 PR        0.0416 0.00689 Inf    0.0281    0.0551

Results are averaged over the levels of: year 
Confidence level used: 0.95 

$contrasts
 contrast  estimate      SE  df z.ratio p.value
 DE - HR  -0.008022 0.00230 Inf  -3.486  0.0014
 DE - PR  -0.007858 0.00713 Inf  -1.102  0.5127
 HR - PR   0.000164 0.00700 Inf   0.023  0.9997

Results are averaged over the levels of: year 
P value adjustment: tukey method for comparing a family of 3 estimates 

exit times not significantly different

LS0tDQp0aXRsZTogIkVhcmx5IG1pZ3JhdGlvbiBwaGVub2xvZ3kgbW9kZWxzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQ0KYGBgDQoNCkFzIGEgcmVtaW5kZXIsIHRoZSBmaWd1cmUgYmVsb3cgZGlzcGxheXMgYSBtaWxlLWhpZ2ggdmlldyBvZiBtaWdyYXRpb24gdGltaW5nIGFjcm9zcyBkaWZmZXJlbnQgc3RyaXBlZCBiYXNzIHNwYXduaW5nIGdyb3VwczogSHVkc29uIFJpdmVyIChIUiksIERlbGF3YXJlIFJpdmVyIChERSksIGFuZCBQb3RvbWFjIFJpdmVyIChQUikuIFRoZSBsZW5ndGggb2YgdGhlIGxpbmUgZGlzcGxheXMgdGhlIHJhbmdlIG9mIHJlc2lkZW5jZSBvZiBlYWNoIGdyb3VwIGluIGVpdGhlciB0aGUgbmF0YWwgZXN0dWFyeSAoY29sb3JzKSBvciBjb2FzdGFsIE1hc3NhY2h1c2V0dHMgKHllbGxvdykuIFRoZSBjaXJjbGUgc2hvd3MgdGhlIG1lZGlhbiBkYXkgb2YgYXJyaXZhbCBpbiB0aGUgZ2l2ZW4gYXJyYXksIGFuZCB0aGUgdHJpYW5nbGUgc2hvd3MgdGhlIG1lZGlhbiBkYXRlIG9mIGRlcGFydHVyZS4gT25seSBmaXNoIHRoYXQgd2VyZSBsYXJnZXIgdGhhbiA4MDAgbW0gYXQgdGhlIHRpbWUgb2YgdGFnZ2luZyBhcmUgc2hvd24uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KGx1YnJpZGF0ZSk7IGxpYnJhcnkoZ2dwbG90Mik7IGxpYnJhcnkoZGF0YS50YWJsZSk7IGxpYnJhcnkoZW1tZWFucykNCg0KDQojIHVtY2VzIDwtIGZyZWFkKCdlbWJhcmdvL2Rlcml2ZWQvdW1jZXNfdGFnX2luZm9fZGV0ZWN0aW9ucy5jc3YnKQ0KdW1jZXMgPC0gdGFyX3JlYWQodW1jZXNfZGV0cykNCiMgQXQgdGhpcyBwb2ludCwgaXQgc2VlbXMgdGhhdCBhbGwgb2YgdGhlIE1BLXRhZ2dlZCBmaXNoIGFyZSBIdWRzb24gaW4gb3JpZ2luDQp1bWNlcyA8LSB1bWNlc1tsb2NhdGlvbiA9PSAnTUEgQ29hc3QnLCBncm91cCA6PSAnSFInXQ0KdW1jZXNbbG9jYXRpb24gIT0gJ01BIENvYXN0JywgZ3JvdXAgOj0gZmlmZWxzZShncmVwbCgnMTMwMycsIHRyYW5zbWl0dGVyKSwgJ0hSJywgJ1BSJyldDQoNCmRucmVjIDwtIHRhcl9yZWFkKGRucmVjX2RldHMpDQpkbnJlY1ssIGdyb3VwIDo9ICdERSddDQpkbnJlY1ssIHRsIDo9IHRvdGFsbGVuZ3RoXQ0KDQpkZXRzIDwtIHJiaW5kKHVtY2VzLCBkbnJlYywgZmlsbCA9IFQpDQoNCmRldHMgPC0gZGV0c1tkYXRldGltZSAlYmV0d2VlbiUgYygnMjAxNi0wMS0wMScsICcyMDIwLTAxLTAxJyldDQoNCnN0YXRpb25fa2V5IDwtIGZyZWFkKCdkYXRhL3N0YXRpb25fa2V5LmNzdicpDQpkZXRzIDwtIHN0YXRpb25fa2V5WywgLihhcnJheSwgc3RhdGlvbm5hbWUpXVtkZXRzLCBvbiA9ICdzdGF0aW9ubmFtZSddDQpkZXRzIDwtIGRldHNbYXJyYXkgIT0gJ0ZBTFNFX0RFVCddDQpkZXRzIDwtIGRldHNbIWlzLm5hKGxhdGl0dWRlKV0NCg0KZGV0c1ssICc6PScoaHIgPSBmbG9vcl9kYXRlKGRhdGV0aW1lLCAnaG91cicpLA0KICAgICAgICAgICAgZGF5ID0gZmxvb3JfZGF0ZShkYXRldGltZSwgJ2RheScpLA0KICAgICAgICAgICAgeWVhciA9IHllYXIoZGF0ZXRpbWUpLA0KICAgICAgICAgICAgeWRheSA9IHlkYXkoZGF0ZXRpbWUpKV0NCg0Kcm0odW1jZXMsIGRucmVjKQ0KYGBgDQoNCg0KYGBge3J9DQpwaGVub19taWcgPC0gZGV0c1t0bCA+PSA4MDAsDQogICAgICAgICAgICAgICAgICAuKG1pbl9kYXRlID0gbWluKHlkYXkpLA0KICAgICAgICAgICAgICAgICAgICBtYXhfZGF0ZSA9IG1heCh5ZGF5KSksDQogICAgICAgICAgICAgICAgICBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAndHJhbnNtaXR0ZXInKV0NCg0KcGhlbm9fbWlnIDwtIHBoZW5vX21pZ1ssIA0KICAgICAgICAgICAgICAgICAgICAgICAuKG1pbl9taW4gPSBtaW4obWluX2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1lZF9taW4gPSBtZWRpYW4obWluX2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1lZF9tYXggPSBtZWRpYW4obWF4X2RhdGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1heF9tYXggPSBtYXgobWF4X2RhdGUpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCnBoZW5vX21pZyA8LSBwaGVub19taWdbZ3JvdXAgPT0gJ1BSJyAmIGFycmF5ID09ICdQb3RvbWFjJyB8DQogICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID09J0RFJyAmIGFycmF5ID09ICdEZWxhd2FyZScgfA0KICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5ID09ICdNQSBDb2FzdCddDQoNCnBoZW5vX21pZ1ssIGFycmF5IDo9IGZhY3RvcihhcnJheSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdQb3RvbWFjJywgJ0RlbGF3YXJlJywgJ0h1ZHNvbicsICdNQSBDb2FzdCcpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUKV0NCg0KcGhlbm9fbWlnWywgZ3JvdXAgOj0gZmFjdG9yKGdyb3VwLA0KICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnUFInLCAnREUnLCAnSFInKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUKV0NCg0KZ2dwbG90KGRhdGEgPSBwaGVub19taWcpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHhtaW4gPSBtaW5fbWluLCB4bWF4ID0gbWF4X21heCwgeSA9IGdyb3VwLCANCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gYXJyYXkpLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNzUpLCBzaXplID0gMSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gbWVkX21pbiwgeSA9IGdyb3VwLCBjb2xvciA9IGFycmF5KSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNzUpLCBzaXplID0gNSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gbWVkX21heCwgeSA9IGdyb3VwLCBjb2xvciA9IGFycmF5KSwgc2hhcGUgPSAndHJpYW5nbGUnLA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC43NSksIHNpemUgPSA1KSArDQogIGZhY2V0X3dyYXAofiB5ZWFyLCBuY29sID0gMSkgKw0KICBsYWJzKHggPSAnRGF5IG9mIHllYXInLCBzdWJ0aXRsZSA9ICdGaXNoID44MDBtbSBhdCB0YWdnaW5nJykgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpJJ20gZ29pbmcgdG8gbWFrZSBhIHF1aWNrLWFuZC1kaXJ0eSBtb2RlbCB0byBjb21wYXJlIHRoZSB0aW1pbmcgb2YgZW50cnkgaW50byBjb2FzdGFsIE1hc3NhY2h1c2V0dHMgYnkgc3Bhd25pbmcgZ3JvdXAuIFRoZSBmdWxsIG1vZGVsIGluY2x1ZGVzIGRheSBvZiB5ZWFyICgieWRheSIsIG51bWVyaWMpLCBzcGF3bmluZyBncm91cCAoImdyb3VwIiwgZmFjdG9yKSwgdGhlIHllYXIgKCJ5ZWFyIiwgb3JkZXJlZCBmYWN0b3IpLCBhbmQgYWxsIGludGVyYWN0aW9ucy4NCg0KVGhlIHJlc3BvbnNlIHdhcyBtb2RlbGVkIGFzIGJpbm9taWFsLCB3aXRoIHRoZSBjdW11bGF0aXZlIG51bWJlciBvZiBmaXNoIHRoYXQgaGF2ZSBlbnRlcmVkIE1hc3NhY2h1c2V0dHMgd2F0ZXJzIHBlciBncm91cC15ZWFyIGNvbWJpbmF0aW9uIGNvbnNpZGVyZWQgInN1Y2Nlc3NlcyIgYW5kIHRoZSB0b3RhbCBudW1iZXIgb2YgZmlzaCB0aGF0IGFycml2ZWQgaW4gY29hc3RhbCBNQSBwZXIgZ3JvdXAteWVhciBjb21iaW5hdGlvbiBhcyB0aGUgbnVtYmVyIG9mIHRyaWFscy4NCg0KVXNpbmcgc3RlcC13aXNlIHZhcmlhYmxlIHNlbGVjdGlvbi4uLg0KDQpgYGB7cn0NCmJpbm9tX2RhdGEgPC0gZGV0c1t0bCA+PSA4MDAgJg0KICAgICAgICAgICAgICAgICAgICAgKGdyb3VwID09ICdQUicgJiBhcnJheSA9PSAnUG90b21hYycgfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0nREUnICYgYXJyYXkgPT0gJ0RlbGF3YXJlJyB8DQogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9PSAnTUEgQ29hc3QnKV0NCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5TRFt3aGljaC5taW4oeWRheSldLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAnYXJyYXknLCAneWVhcicsICd0cmFuc21pdHRlcicpXQ0KdHJpYWxzIDwtIGJpbm9tX2RhdGFbLCAuKHRyaWFscyA9IC5OKSwgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5OLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAneWRheScpXQ0Kc2V0b3JkZXIoYmlub21fZGF0YSwgZ3JvdXAsIGFycmF5LCB5ZWFyLCB5ZGF5KQ0KYmlub21fZGF0YVssIHN1Y2Nlc3MgOj0gY3Vtc3VtKE4pLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInKV0NCg0KYmlub21fZGF0YSA8LSBiaW5vbV9kYXRhW3RyaWFscywgb24gPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQpiaW5vbV9kYXRhWywgeWVhciA6PSBmYWN0b3IoeWVhciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBzZXEoMjAxNiwgMjAxOSwgMSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFQpXQ0KDQpmdWxsX21vZGVsIDwtIGdsbShjYmluZChzdWNjZXNzLCB0cmlhbHMgLSBzdWNjZXNzKSB+DQogICAgICAgICAgICAgICAgICAwICsgZ3JvdXAgKyB5ZGF5ICsgeWVhciArIGdyb3VwOnlkYXkgKyBncm91cDp5ZWFyICsgeWVhcjp5ZGF5ICsNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXA6eWVhcjp5ZGF5LA0KICAgICAgICAgICAgICAgICAgZGF0YSA9IGJpbm9tX2RhdGFbYXJyYXkgPT0gJ01BIENvYXN0J10sDQogICAgICAgICAgICAgICAgICBmYW1pbHkgPSAnYmlub21pYWwnKQ0KDQptb2RfYXJyaXZhbCA8LSBzdGVwKGZ1bGxfbW9kZWwpDQpgYGANCg0KLi4udGhlIHZhcmlhYmxlcyBzZWxlY3RlZCBhcmU6IGByIHBhc3RlKGNvbG5hbWVzKGF0dHIodGVybXMobW9kX2Fycml2YWwpLCAnZmFjdG9ycycpKSwgY29sbGFwc2UgPSAiLCAiKWAuDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RfYXJyaXZhbCkNCmBgYA0KDQpXaGVuIGxvb2tpbmcgYXQgcGFpcndpc2UgY29udHJhc3RzIGJ5IHllYXIsIHRoZSBvbmx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIG9jY3VyIGluIDIwMTgsIHdoZXJlIGFycml2YWwgaW4gTUEgd2FzIG1vcmUgcmFwaWQgaW4gREUgYW5kIFBSIGZpc2ggd2hlbiBjb21wYXJlZCB0byBIUiBmaXNoIChncmVhdGVyIHlkYXkgc2xvcGUpLg0KDQpgYGB7cn0NCmVtdHJlbmRzKG1vZF9hcnJpdmFsLCBwYWlyd2lzZSB+IGdyb3VwIHwgeWVhciwgdmFyID0gInlkYXkiKSRjb250cmFzdHMNCg0KZW1tZWFucyhtb2RfYXJyaXZhbCwgcGFpcndpc2UgfiBncm91cCB8IHllYXIsIGNvdi5rZWVwID0gJ3lkYXknKQ0KDQplbW1pcChtb2RfYXJyaXZhbCwgZ3JvdXAgfiB5ZGF5IHwgeWVhciwgY292LmtlZXAgPSAneWRheScsIENJcyA9IFQpDQpgYGANCg0KDQpgYGB7cn0NCnJhbmdlX2tleSA8LSAgYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnLA0KICAgICAgICAgICAgICAgICAgICAgICAgIC4obWluID0gbWluKHlkYXkpLCBtYXggPSBtYXgoeWRheSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAneWVhcicpXQ0Kc2V0a2V5KHJhbmdlX2tleSwgZ3JvdXAsIHllYXIsIG1pbiwgbWF4KQ0KbmV3X2RhdGEgPC0gZXhwYW5kLmdyaWQoZ3JvdXAgPSBjKCdIUicsICdQUicsICdERScpLA0KICAgICAgICAgICAgICAgICAgICAgICAgeWRheSA9IHNlcShtaW4oYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSR5ZGF5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGJpbm9tX2RhdGFbYXJyYXkgPT0gJ01BIENvYXN0J10keWRheSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aC5vdXQgPSAyMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IGMoJzIwMTYnLCAnMjAxNycsICcyMDE4JywgJzIwMTknKSkNCnNldERUKG5ld19kYXRhKQ0KbmV3X2RhdGFbLCB5ZGF5MiA6PSB5ZGF5XQ0Kc2V0a2V5KG5ld19kYXRhLCAgZ3JvdXAsIHllYXIsIHlkYXksIHlkYXkyKQ0KDQpuZXdfZGF0YSA8LSBmb3ZlcmxhcHMocmFuZ2Vfa2V5LCBuZXdfZGF0YSkNCg0KcHJlZCA8LSBwcmVkaWN0KG1vZF9hcnJpdmFsLA0KICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YSwNCiAgICAgICAgICAgICAgICB0eXBlID0gJ2xpbmsnLCBzZS5maXQgPSBUKQ0KcHJlZCA8LSBkYXRhLmZyYW1lKG5ld19kYXRhLA0KICAgICAgICAgICAgICAgICAgIHByZWQgPSBwcmVkKQ0KDQpzZXREVChwcmVkKVssICc6PScocHJlZCA9IG1vZF9hcnJpdmFsJGZhbWlseSRsaW5raW52KHByZWQuZml0KSwNCiAgICAgICAgICAgICAgICAgICBsY2kgPSBtb2RfYXJyaXZhbCRmYW1pbHkkbGlua2ludihwcmVkLmZpdCAtIHByZWQuc2UuZml0KSwNCiAgICAgICAgICAgICAgICAgICB1Y2kgPSBtb2RfYXJyaXZhbCRmYW1pbHkkbGlua2ludihwcmVkLmZpdCArIHByZWQuc2UuZml0KSldDQpwbG90bHk6OmdncGxvdGx5KA0KZ2dwbG90KGRhdGEgPSBwcmVkKSArDQogIGdlb21fcmliYm9uKGFlcyh4ID0geWRheSwgeW1heCA9IHVjaSwgeW1pbiA9IGxjaSwgZmlsbCA9IGdyb3VwKSwgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0geWRheSwgeSA9IHByZWQsIGdyb3VwID0gZ3JvdXApKSArDQogIGZhY2V0X3dyYXAofnllYXIpICsNCiAgbGFicyhzdWJ0aXRsZSA9ICdNb2RlbGVkIGFycml2YWwgaW4gY29hc3RhbCBNQScpDQopDQpgYGANCg0KRW50cnkgaW50byBNQSB3YXRlcnMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBERSBhbmQgSFIgZmlzaCwgYnV0IG5vdCBiZXR3ZWVuIFBSIGFuZCBIUiBvciBQUiBhbmQgREUgZmlzaC4NCg0KDQpgYGB7cn0NCmJpbm9tX2RhdGEgPC0gZGV0c1t0bCA+PSA4MDAgJg0KICAgICAgICAgICAgICAgICAgICAgKGdyb3VwID09ICdQUicgJiBhcnJheSA9PSAnUG90b21hYycgfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0gJ0hSJyAmIGFycmF5ID09ICdIdWRzb24nfA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPT0nREUnICYgYXJyYXkgPT0gJ0RlbGF3YXJlJyB8DQogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9PSAnTUEgQ29hc3QnKV0NCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5TRFt3aGljaC5tYXgoeWRheSldLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnZ3JvdXAnLCAnYXJyYXknLCAneWVhcicsICd0cmFuc21pdHRlcicpXQ0KdHJpYWxzIDwtIGJpbm9tX2RhdGFbLCAuKHRyaWFscyA9IC5OKSwgYnkgPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQoNCmJpbm9tX2RhdGEgPC0gYmlub21fZGF0YVssIC5OLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInLCAneWRheScpXQ0Kc2V0b3JkZXIoYmlub21fZGF0YSwgZ3JvdXAsIGFycmF5LCB5ZWFyLCB5ZGF5KQ0KYmlub21fZGF0YVssIHN1Y2Nlc3MgOj0gY3Vtc3VtKE4pLCBieSA9IGMoJ2dyb3VwJywgJ2FycmF5JywgJ3llYXInKV0NCg0KYmlub21fZGF0YSA8LSBiaW5vbV9kYXRhW3RyaWFscywgb24gPSBjKCdncm91cCcsICdhcnJheScsICd5ZWFyJyldDQpiaW5vbV9kYXRhWywgeWVhciA6PSBhcy5mYWN0b3IoeWVhcildDQoNCmZ1bGxfbW9kZWwgPC0gZ2xtKGNiaW5kKHN1Y2Nlc3MsIHRyaWFscyAtIHN1Y2Nlc3MpIH4NCiAgICAgICAgICAgICAgICAgICAwICsgZ3JvdXAgKyB5ZGF5ICsgZ3JvdXA6eWRheSArIHllYXIsDQogICAgICAgICAgICAgICAgICBkYXRhID0gYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSwNCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9ICdiaW5vbWlhbCcpDQoNCm1vZF9kZXBhcnR1cmUgPC0gc3RlcChmdWxsX21vZGVsKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RfZGVwYXJ0dXJlKQ0KDQplbXRyZW5kcyhtb2RfZGVwYXJ0dXJlLCBwYWlyd2lzZSB+IGdyb3VwLCB2YXIgPSAieWRheSIpDQplbW1pcChtb2RfZGVwYXJ0dXJlLCBncm91cCB+IHlkYXksIGNvdi5yZWR1Y2UgPSByYW5nZSwgQ0lzID0gVCkNCmBgYA0KDQoNCmV4aXQgdGltZXMgbm90IHNpZ25pZmljYW50bHkgZGlmZmVyZW50DQoNCmBgYHtyfQ0KcmFuZ2Vfa2V5IDwtICBiaW5vbV9kYXRhW2FycmF5ID09ICdNQSBDb2FzdCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgLihtaW4gPSBtaW4oeWRheSksIG1heCA9IG1heCh5ZGF5KSksDQogICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdncm91cCcsICd5ZWFyJyldDQpzZXRrZXkocmFuZ2Vfa2V5LCBncm91cCwgbWluLCBtYXgpDQpuZXdfZGF0YSA8LSBleHBhbmQuZ3JpZChncm91cCA9IGMoJ0hSJywgJ1BSJywgJ0RFJyksDQogICAgICAgICAgICAgICAgICAgICAgICB5ZGF5ID0gc2VxKG1pbihiaW5vbV9kYXRhW2FycmF5ID09ICdNQSBDb2FzdCddJHlkYXkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoYmlub21fZGF0YVthcnJheSA9PSAnTUEgQ29hc3QnXSR5ZGF5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLm91dCA9IDIwMCksDQogICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID0gYygnMjAxNicsICcyMDE3JywgJzIwMTgnLCAnMjAxOScpKQ0Kc2V0RFQobmV3X2RhdGEpDQpuZXdfZGF0YVssIHlkYXkyIDo9IHlkYXldDQpzZXRrZXkobmV3X2RhdGEsICBncm91cCwgeWRheSwgeWRheTIpDQoNCm5ld19kYXRhIDwtIGZvdmVybGFwcyhyYW5nZV9rZXksIG5ld19kYXRhKQ0KDQpwcmVkIDwtIHByZWRpY3QobW9kX2RlcGFydHVyZSwNCiAgICAgICAgICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGEsDQogICAgICAgICAgICAgICAgdHlwZSA9ICdsaW5rJywgc2UuZml0ID0gVCkNCnByZWQgPC0gZGF0YS5mcmFtZShuZXdfZGF0YSwNCiAgICAgICAgICAgICAgICAgICBwcmVkID0gcHJlZCkNCg0Kc2V0RFQocHJlZClbLCAnOj0nKHByZWQgPSBtb2RfZGVwYXJ0dXJlJGZhbWlseSRsaW5raW52KHByZWQuZml0KSwNCiAgICAgICAgICAgICAgICAgICBsY2kgPSBtb2RfZGVwYXJ0dXJlJGZhbWlseSRsaW5raW52KHByZWQuZml0IC0gcHJlZC5zZS5maXQpLA0KICAgICAgICAgICAgICAgICAgIHVjaSA9IG1vZF9kZXBhcnR1cmUkZmFtaWx5JGxpbmtpbnYocHJlZC5maXQgKyBwcmVkLnNlLmZpdCkpXQ0KDQpnZ3Bsb3QoZGF0YSA9IHByZWQpICsNCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZGF5LCB5bWF4ID0gdWNpLCB5bWluID0gbGNpLCBmaWxsID0gZ3JvdXApLCBhbHBoYSA9IDAuNSkgKw0KICBnZW9tX2xpbmUoYWVzKHggPSB5ZGF5LCB5ID0gcHJlZCwgZ3JvdXAgPSBncm91cCkpICsNCiAgZmFjZXRfd3JhcCh+eWVhcikgKw0KICBsYWJzKHN1YnRpdGxlID0gJ01vZGVsZWQgZGVwYXJ0dXJlIGluIGNvYXN0YWwgTUEnKQ0KYGBgDQo=